#include "tcp.h"
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>

/*
    udp_t udp;
    struct sockaddr_in addr;
    uv_ip4_addr("0.0.0.0", 1234, &addr);
    udp_createhandler(&udp, (struct sockaddr *)&addr, sizeof(addr));
    udp_recv_start(&udp, udp_recved);
    sleep(10);
    udp_recv_stop(&udp);
    sleep(10);
    udp_recv_start(&udp, udp_recved);

*/
static void onreceive(RecvReq_t* req, ssize_t nread, const uv_buf_t* buf, const struct sockaddr* addr, unsigned flags);
void shutdown_cb(ReqCommon_t* req, int status)
{
    if(status){
        printf("%s %d %s\n", __func__, status, strerror(errno));
    }else{
        printf("%s %d %s\n", __func__, status, strerror(errno));
    }
    free(req);
}

static void send_cb(SendReq_t * req, int status)
{

    if(status){
        printf("%s ret = %s\n", __func__, strerror(status));
    }else{
        printf("%s ret = %d\n", __func__, status);
        tcp_recv_start(req->handle, onreceive);
    }
}

char *readfromfile(const char *path, long *len)
{
    char *buf;
    FILE *f = fopen(path, "rb");
    if(f){
        fseek(f, 0, SEEK_END);
        long leng = ftell(f);
        fseek(f, 0, SEEK_SET);
        buf = malloc(leng);
        fread(buf, 1, leng, f);
        *len = leng;
    }

    return buf;

}

void onreceive(RecvReq_t* req, ssize_t nread, const uv_buf_t* buf, const struct sockaddr* addr, unsigned flags)
{
    tcp_t *tcp = req->handle;

    printf("%s %d -> %zd\n", __func__, tcp->socket, nread);
    if(nread == 0){
        ReqCommon_t *shutdownReq = malloc(sizeof(ReqCommon_t));
        tcp_shutdown(shutdownReq, tcp, shutdown_cb);
        tcp_close(shutdownReq, tcp, NULL);
    }

    SendReq_t *sendreq = malloc(sizeof(SendReq_t));

    // long length;
    // char *nbuf = readfromfile("/home/firear/fcb62edc7cadb12dc2f8e666fa351f8e.ipa", &length);
    tcp_send(sendreq, tcp, buf->base, nread, send_cb);

}

void connection_cb(tcp_t* server, int status)
{
    tcp_t *client = (tcp_t *)malloc(sizeof(tcp_t));
    tcp_createhandler(client, NULL, 0);
    int ret = tcp_accept(server, client);

    tcp_recv_start(client, onreceive);
    tcp_listen(server, 10, connection_cb);
}

void client_connect_cb(tcp_t* client, int status)
{
    printf("%s %d\n", __func__, status);
    if(status == ECONNREFUSED){ // 失败


    }else if(status == 0){ //成功
        tcp_recv_start(client, onreceive);
    }else{

    }

}

int main(int argc, char const *argv[])
{
    tcp_t handler;
    /*
    tcp_t handler2;

    #include "cmap.h"
    CMAP *cmap = cmap_new();
    cmap_put2(cmap, &handler, sizeof(void *), (void *)1, NULL);
    cmap_put2(cmap, &handler2, sizeof(void *), (void *)1, NULL);

    void *ret = cmap_get(cmap, &handler,  sizeof(void *));
    ret = cmap_get(cmap, &handler2,  sizeof(void *));
    */

    struct sockaddr_in addr;
    tcp_init();

    uv_ip4_addr("0.0.0.0", 1234, &addr);
    tcp_createhandler(&handler, (struct sockaddr *)&addr, sizeof(addr));

    if(argv[1][0] == '1'){
        tcp_listen(&handler, 10, connection_cb);
    }else{
        uv_ip4_addr("0.0.0.0", 1235, &addr);
        tcp_connect(&handler,  (struct sockaddr *)&addr, sizeof(addr), client_connect_cb);
    }


    while (1){
        sleep(10);
    }

    sleep(10);

    return 0;
}
